#include "behaviortree_cpp_v3/bt_factory.h"
#include "behaviortree_cpp_v3/actions/script_node.h"
#include "behaviortree_cpp_v3/actions/script_condition.h"

#include "behaviortree_cpp_v3/loggers/bt_cout_logger.h"
#include "behaviortree_cpp_v3/loggers/bt_minitrace_logger.h"
#include "behaviortree_cpp_v3/loggers/bt_file_logger.h"
#include "sol/sol.hpp"
#include <fstream>
#include <string>

#ifdef ZMQ_FOUND
#include "behaviortree_cpp_v3/loggers/bt_zmq_publisher.h"
#endif

using namespace BT;

/** Behavior Tree are used to create a logic to decide what
 * to "do" and when. For this reason, our main building blocks are
 * Actions and Conditions.
 *
 * In this tutorial, we will learn how to create custom ActionNodes.
 * It is important to remember that NodeTree are just a way to
 * invoke callbacks (called tick() ). These callbacks are implemented by the user.
 */

int main()
{
    // We use the BehaviorTreeFactory to register our custom nodes

    BehaviorTreeFactory factory;
    factory.registerFromPlugin("../sample_nodes/liblaser_node_dyn.dll");

    auto tree = factory.createTreeFromFile("./laser.xml");

    StdCoutLogger logger_cout(tree);

    // This logger saves state changes on file
    FileLogger logger_file(tree, "bt_trace_false.fbl");

#ifdef ZMQ_FOUND
  // This logger publish status changes using ZeroMQ. Used by Groot
  PublisherZMQ publisher_zmq(tree);
#endif

    tree.tickRootWhileRunning();

    return 0;
}

